import {
  IsBoolean,
  IsEmail,
  IsNotEmpty,
  IsNumber,
  IsOptional,
  IsString,
  MaxLength,
  MinLength,
  Validate,
} from 'class-validator';
import { applyDecorators } from '@nestjs/common'; // 装饰器工具函数,组合装饰器
import { Type } from 'class-transformer';
import { PartialType, OmitType } from '@nestjs/mapped-types';
import {
  IsUsernameUniqueConstraint,
  StartsWith,
  // StartsWithConstraint,
} from '../validators/user-validator';
import {
  IdValidate,
  StatusValidate,
  SortValidate,
} from '../decorators/dto.decorator';
import {
  ApiProperty,
  ApiPropertyOptional,
  PartialType as PartialTypeFromSwagger,
} from '@nestjs/swagger';
import { i18nValidationMessage } from 'nestjs-i18n';

export class CreateUserDto {
  @IsString()
  // @Validate(StartsWithConstraint)
  // @StartsWith('user_') // 支持传参
  @Validate(IsUsernameUniqueConstraint, ['user_'], {
    message: i18nValidationMessage('validation.usernameIsNotUnique'),
  })
  @ApiProperty({ description: '用户名', example: 'nick' })
  username: string;

  @PasswordValidate()
  @ApiProperty({ description: '密码', example: '123456' })
  password: string;

  @EmailValidate()
  @ApiProperty({ description: '邮箱', example: '123456@qq.com' })
  email: string;

  @MobileValidate()
  @ApiProperty({ description: '手机号', example: '15200000000' })
  @ApiPropertyOptional() // swagger文档该字段允许为空
  phone: string;

  @StatusValidate()
  @ApiProperty({ description: '生效状态', example: 1 })
  status: number;

  @IsSuperValidate()
  @ApiProperty({ description: '是否是超级管理员', example: true })
  is_super: boolean;

  @SortValidate()
  @ApiProperty({ description: '排序编号', example: 100 })
  sort: number;
}

export class UpdateUserDto extends PartialTypeFromSwagger(
  OmitType(PartialType(CreateUserDto), ['password', 'username']),
) {
  @IdValidate()
  id: number;

  @IsString()
  @ApiProperty({ description: '用户名', example: 'nick' })
  @IsOptional()
  username: string;

  @ApiProperty({ description: '密码', example: '123456' })
  @IsOptional()
  password: string;
}

/**
 * 1. applyDecorators 组合装饰器
 * 2. 装饰器的执行顺序是从下往上，从右往左
 * 3. 装饰器工厂函数的返回值是一个装饰器函数
 */
function PasswordValidate() {
  return applyDecorators(
    IsString(),
    IsNotEmpty({
      message: i18nValidationMessage('validation.isNotEmpty', {
        field: 'password',
      }),
    }),
    MinLength(6, {
      // 多语言配置提示信息
      message: i18nValidationMessage('validation.minlength', {
        field: 'password',
        length: 6,
      }),
    }),
    MaxLength(8, {
      message: i18nValidationMessage('validation.maxlength', {
        field: 'password',
        length: 8,
      }),
    }),
  );
}

function EmailValidate() {
  return applyDecorators(
    IsNotEmpty({
      message: i18nValidationMessage('validation.isNotEmpty', {
        field: 'email',
      }),
    }),
    IsEmail(),
    IsOptional(),
  );
}

function MobileValidate() {
  return applyDecorators(IsString(), IsOptional());
}

function IsSuperValidate() {
  // Type 转换类型
  return applyDecorators(
    IsBoolean(),
    IsOptional(),
    Type(() => Boolean),
  );
}
